/**
 * 错误处理工具类
 * 提供统一的错误处理、重试机制和用户友好的错误提示
 */

// 错误类型枚举
export const ErrorTypes = {
  NETWORK_ERROR: 'NETWORK_ERROR',
  TIMEOUT_ERROR: 'TIMEOUT_ERROR',
  API_KEY_ERROR: 'API_KEY_ERROR',
  RATE_LIMIT_ERROR: 'RATE_LIMIT_ERROR',
  SERVER_ERROR: 'SERVER_ERROR',
  UNKNOWN_ERROR: 'UNKNOWN_ERROR',
  CONTENT_FILTER_ERROR: 'CONTENT_FILTER_ERROR',
  QUOTA_EXCEEDED_ERROR: 'QUOTA_EXCEEDED_ERROR'
}

// 错误严重程度
export const ErrorSeverity = {
  LOW: 'low',
  MEDIUM: 'medium',
  HIGH: 'high',
  CRITICAL: 'critical'
}

// 错误处理配置
const ERROR_CONFIG = {
  maxRetries: 3,
  baseRetryDelay: 1000, // 1秒
  maxRetryDelay: 10000, // 10秒
  exponentialBackoff: true,
  retryableErrors: [
    ErrorTypes.NETWORK_ERROR,
    ErrorTypes.TIMEOUT_ERROR,
    ErrorTypes.SERVER_ERROR
  ]
}

/**
 * 错误分析器
 * 分析错误类型、严重程度和处理策略
 */
export class ErrorAnalyzer {
  static analyze(error) {
    const result = {
      type: ErrorTypes.UNKNOWN_ERROR,
      severity: ErrorSeverity.MEDIUM,
      message: '服务暂时不可用，请稍后重试',
      userMessage: '抱歉，服务遇到问题，请稍后重试',
      retryable: false,
      retryDelay: ERROR_CONFIG.baseRetryDelay,
      showRetryButton: false,
      logLevel: 'error',
      context: {}
    }

    if (!error) {
      return result
    }

    // 网络错误
    if (this.isNetworkError(error)) {
      result.type = ErrorTypes.NETWORK_ERROR
      result.severity = ErrorSeverity.HIGH
      result.message = '网络连接异常'
      result.userMessage = '网络连接不稳定，请检查网络后重试'
      result.retryable = true
      result.showRetryButton = true
      result.logLevel = 'warn'
      return result
    }

    // 超时错误
    if (this.isTimeoutError(error)) {
      result.type = ErrorTypes.TIMEOUT_ERROR
      result.severity = ErrorSeverity.MEDIUM
      result.message = '请求超时'
      result.userMessage = '请求处理时间较长，正在重试...'
      result.retryable = true
      result.retryDelay = ERROR_CONFIG.baseRetryDelay * 2
      return result
    }

    // HTTP状态码错误
    if (error.response?.status) {
      return this.analyzeHttpError(error.response.status, error.response.data)
    }

    // API响应错误
    if (error.response?.data) {
      return this.analyzeApiError(error.response.data)
    }

    return result
  }

  static isNetworkError(error) {
    return (
      error.code === 'NETWORK_ERROR' ||
      error.message?.includes('Network Error') ||
      error.message?.includes('ERR_NETWORK') ||
      !navigator.onLine
    )
  }

  static isTimeoutError(error) {
    return (
      error.code === 'ECONNABORTED' ||
      error.message?.includes('timeout') ||
      error.message?.includes('TIMEOUT')
    )
  }

  static analyzeHttpError(status, data) {
    const result = {
      type: ErrorTypes.SERVER_ERROR,
      severity: ErrorSeverity.MEDIUM,
      retryable: false,
      showRetryButton: false,
      logLevel: 'error',
      context: { status, data }
    }

    switch (status) {
      case 400:
        result.type = ErrorTypes.UNKNOWN_ERROR
        result.severity = ErrorSeverity.LOW
        result.message = '请求参数错误'
        result.userMessage = '请求格式有误，请重新尝试'
        break

      case 401:
        result.type = ErrorTypes.API_KEY_ERROR
        result.severity = ErrorSeverity.CRITICAL
        result.message = 'API密钥无效或已过期'
        result.userMessage = 'API配置错误，请联系管理员'
        break

      case 403:
        result.type = ErrorTypes.CONTENT_FILTER_ERROR
        result.severity = ErrorSeverity.MEDIUM
        result.message = '内容被过滤或权限不足'
        result.userMessage = '您的请求包含敏感内容，请重新组织语言'
        break

      case 429:
        result.type = ErrorTypes.RATE_LIMIT_ERROR
        result.severity = ErrorSeverity.MEDIUM
        result.message = '请求频率过高'
        result.userMessage = '请求过于频繁，请稍后重试'
        result.retryable = true
        result.retryDelay = ERROR_CONFIG.baseRetryDelay * 3
        break

      case 500:
      case 502:
      case 503:
      case 504:
        result.type = ErrorTypes.SERVER_ERROR
        result.severity = ErrorSeverity.HIGH
        result.message = '服务器内部错误'
        result.userMessage = '服务暂不可用，正在重试...'
        result.retryable = true
        result.showRetryButton = true
        break

      default:
        result.message = `HTTP错误 ${status}`
        result.userMessage = `服务错误 (${status})，请稍后重试`
        result.showRetryButton = true
    }

    return result
  }

  static analyzeApiError(data) {
    const result = {
      type: ErrorTypes.UNKNOWN_ERROR,
      severity: ErrorSeverity.MEDIUM,
      message: '服务响应错误',
      userMessage: '服务处理异常，请稍后重试',
      retryable: false,
      showRetryButton: false,
      logLevel: 'error',
      context: { data }
    }

    return result
  }
}

/**
 * 重试管理器
 * 处理自动重试逻辑
 */
export class RetryManager {
  constructor(config = {}) {
    this.config = { ...ERROR_CONFIG, ...config }
    this.retryCount = 0
    this.retryHistory = []
  }

  canRetry(errorAnalysis) {
    return (
      this.retryCount < this.config.maxRetries &&
      errorAnalysis.retryable &&
      this.config.retryableErrors.includes(errorAnalysis.type)
    )
  }

  getRetryDelay(errorAnalysis) {
    let delay = errorAnalysis.retryDelay || this.config.baseRetryDelay

    if (this.config.exponentialBackoff) {
      delay = Math.min(
        delay * Math.pow(2, this.retryCount),
        this.config.maxRetryDelay
      )
    }

    // 添加随机抖动，避免雷群效应
    const jitter = Math.random() * 0.1 * delay
    return Math.floor(delay + jitter)
  }

  async executeWithRetry(operation, onProgress) {
    this.retryCount = 0
    this.retryHistory = []

    while (true) {
      try {
        const result = await operation()
        this.reset()
        return result
      } catch (error) {
        const errorAnalysis = ErrorAnalyzer.analyze(error)
        this.retryHistory.push({
          attempt: this.retryCount + 1,
          error: errorAnalysis,
          timestamp: Date.now()
        })

        if (!this.canRetry(errorAnalysis)) {
          throw { ...error, analysis: errorAnalysis, retryHistory: this.retryHistory }
        }

        this.retryCount++
        const delay = this.getRetryDelay(errorAnalysis)

        // 通知重试进度
        if (onProgress) {
          onProgress({
            attempt: this.retryCount,
            maxAttempts: this.config.maxRetries,
            delay,
            error: errorAnalysis
          })
        }

        await this.sleep(delay)
      }
    }
  }

  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
  }

  reset() {
    this.retryCount = 0
    this.retryHistory = []
  }

  getRetryStatus() {
    return {
      currentAttempt: this.retryCount,
      maxAttempts: this.config.maxRetries,
      history: this.retryHistory
    }
  }
}

/**
 * 错误日志记录器
 * 记录和上报错误信息
 */
export class ErrorLogger {
  static log(error, context = {}) {
    const logEntry = {
      timestamp: new Date().toISOString(),
      error: {
        message: error.message,
        stack: error.stack,
        type: error.type || 'unknown'
      },
      context,
      userAgent: navigator.userAgent,
      url: window.location.href
    }

    // 根据错误级别选择日志方法
    const logLevel = error.analysis?.logLevel || 'error'
    switch (logLevel) {
      case 'warn':
        console.warn('错误警告:', logEntry)
        break
      case 'error':
        console.error('错误记录:', logEntry)
        break
      case 'info':
        console.info('错误信息:', logEntry)
        break
      default:
        console.log('错误日志:', logEntry)
    }
  }
}

/**
 * 主错误处理器
 * 统一的错误处理入口
 */
export class ErrorHandler {
  constructor(config = {}) {
    this.retryManager = new RetryManager(config)
    this.errorCallbacks = new Map()
  }

  // 注册错误回调
  onError(errorType, callback) {
    if (!this.errorCallbacks.has(errorType)) {
      this.errorCallbacks.set(errorType, [])
    }
    this.errorCallbacks.get(errorType).push(callback)
  }

  // 处理错误
  async handle(error, context = {}) {
    const errorAnalysis = ErrorAnalyzer.analyze(error)
    
    // 记录错误
    ErrorLogger.log(error, { ...context, analysis: errorAnalysis })

    // 触发错误回调
    this.triggerCallbacks(errorAnalysis.type, errorAnalysis)

    return errorAnalysis
  }

  // 带重试的操作执行
  async executeWithRetry(operation, options = {}) {
    const { onProgress, context = {} } = options
    
    try {
      return await this.retryManager.executeWithRetry(operation, onProgress)
    } catch (error) {
      const errorAnalysis = await this.handle(error, context)
      throw { ...error, analysis: errorAnalysis }
    }
  }

  // 触发错误回调
  triggerCallbacks(errorType, errorAnalysis) {
    const callbacks = this.errorCallbacks.get(errorType) || []
    const globalCallbacks = this.errorCallbacks.get('*') || []
    
    const allCallbacks = [...callbacks, ...globalCallbacks]
    allCallbacks.forEach(callback => {
      try {
        callback(errorAnalysis)
      } catch (callbackError) {
        console.warn('错误回调执行失败:', callbackError)
      }
    })
  }

  // 获取重试状态
  getRetryStatus() {
    return this.retryManager.getRetryStatus()
  }

  // 重置重试计数
  reset() {
    this.retryManager.reset()
  }
}

// 创建全局错误处理器实例
export const globalErrorHandler = new ErrorHandler()

// 导出便捷函数
export const handleError = (error, context) => globalErrorHandler.handle(error, context)
export const executeWithRetry = (operation, options) => globalErrorHandler.executeWithRetry(operation, options)